package com.lwq.code;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * Description:
 * Author: LiuWenQing
 * Datetime: 2021/6/16
 */
@Component
public class WebSocketServer {

    @Value("${netty.server.port}")
    private Integer port;

    private EventLoopGroup boss;
    private EventLoopGroup work;

    @PostConstruct()
    public void init() {
        new Thread(this::startServer).start();
    }

    private void startServer() {
        //服务端需要2个线程组  boss处理客户端连接  work进行客服端连接之后的处理
        createWebEventGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(boss, work)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new com.lwq.code.WebSocketChannelInitializer())
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture  channel = bootstrap.bind(port).sync();
            channel.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            boss.shutdownGracefully();
            work.shutdownGracefully();
        }
    }


    private void createWebEventGroup(){
        boss = new  NioEventLoopGroup();
        work = new NioEventLoopGroup();
    }

    public void destroy(EventLoopGroup bossGroup , EventLoopGroup workerGroup) {
        if(bossGroup != null && !bossGroup.isShuttingDown() && !bossGroup.isShutdown() ) {
            try {bossGroup.shutdownGracefully();}catch(Exception ignore) {}
        }

        if(workerGroup != null && !workerGroup.isShuttingDown() && !workerGroup.isShutdown() ) {
            try {workerGroup.shutdownGracefully();}catch(Exception ignore) {}
        }
    }
}
